package main

import (
	"fmt"
	"go-xorm-01/utils"
	"xorm.io/xorm"
	"xorm.io/xorm/log"
	"xorm.io/xorm/names"
)

var engine *xorm.Engine

// Join的使用: https://xorm.io/zh/docs/chapter-05/5.join/
// Join(string,interface{},string)
// 第一个参数为连接类型，当前支持INNER, LEFT OUTER, CROSS中的一个值， 第二个参数为string类型的表名，表对应的结构体指针或者为两个值的[]string，表示表名和别名， 第三个参数为连接条件。
//
// 以下将通过示例来讲解具体的用法：
func main() {
	SnakeMapper()
	//insetManyUser(engine)
	//engine.DumpAllToFile("demo05-query/demo08-join/sql.sql")
	queryUser(engine)
}

func queryUser(engine *xorm.Engine) {
	users := make([]UserGroupU, 0)
	err := engine.Join("INNER", "group_u", "group_u.id = user_u.group_id").Limit(2).Find(&users)
	if err != nil {
		fmt.Printf("err:%v", err)
	}
	fmt.Println("Join查询：", users)

	users1 := make([]UserGroupU, 0)
	engine.SQL("select user.*, group.name from user, group where user.group_id = group.id").Limit(2).Find(&users1)
	fmt.Println("Join-SQL查询：", users)

	users2 := make([]UserGroupB, 0)
	engine.Join("INNER", "group_u", "group_u.id = user_u.group_id").Limit(2).Find(&users2)
	fmt.Println("Join-查询查询：", users2)
}

func SnakeMapper() {
	engine = utils.GenerateEngine()
	engine.SetMapper(names.SnakeMapper{}) // SnakeMapper 【默认】
	err := engine.Sync2(new(GroupU), new(UserU))
	if err != nil {
		fmt.Printf("err:%v", err)
	}
	engine.ShowSQL(true)
	engine.SetLogLevel(log.LOG_DEBUG)

}

func insetManyUser(engine *xorm.Engine) {
	engine.Insert(GroupU{
		Name: "group-one",
	})
	for i := 0; i <= 3; i++ {
		engine.Insert(UserU{
			Name:    fmt.Sprintf("zhangsan-%d", i),
			GroupId: 1,
		})
	}
	engine.Insert(GroupU{
		Name: "group-two",
	})
	for i := 0; i <= 3; i++ {
		engine.Insert(UserU{
			Name:    fmt.Sprintf("lisi-%d", i),
			GroupId: 2,
		})
	}

}

// -------------------------
type GroupU struct {
	Id   int64 `xorm:"pk autoincr"`
	Name string
}

func (u GroupU) TableName() string {
	return "group_u"
}

// -------------------------
type UserU struct {
	Id      int64 `xorm:"pk autoincr"`
	Name    string
	GroupId int64 `xorm:"index"`
}

func (u UserU) TableName() string {
	return "user_u"
}

// -------------------------
type UserGroupU struct {
	UserU `xorm:"extends"`
	Name  string
}

func (u UserGroupU) TableName() string {
	return "user_u"
}

// -------------------------
type UserGroupB struct {
	UserU  `xorm:"extends"`
	GroupU `xorm:"extends"`
}

func (u UserGroupB) TableName() string {
	return "user_u"
}
